package com.ruoyi.system.service.impl;

import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.config.FileConfig;
import com.ruoyi.common.config.MinioTemplate;
import com.ruoyi.common.exception.JGException;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysTraining;
import com.ruoyi.system.domain.param.SysTrainingPageParam;
import com.ruoyi.system.domain.vo.SysTrainingVo;
import com.ruoyi.system.mapper.SysTrainingMapper;
import com.ruoyi.system.service.ISysTrainingService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/***
 *@title ISysShopServiceImpl
 *@description <TODO 培训管理——业务处理层>
 *@author 然子哥
 *@version 1.0.0
 *@create 2023/5/18 10:05
 **/
@Service
@RequiredArgsConstructor
public class SysTrainingServiceImpl extends ServiceImpl<SysTrainingMapper, SysTraining> implements ISysTrainingService {

    private final FileConfig fileConfig;
    private final MinioTemplate minioTemplate;

    /**
     * TODO 分页查询培训列表
     *
     * @param page  页数
     * @param limit 每页限制条数
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.system.labor.entity.outside.SysShop>
     * @author 然子哥
     * @date 2023/5/18 10:20
     */
    @Override
    public IPage<SysTraining> selectPage(Long page, Long limit) {
        Page<SysTraining> pageParam = new Page<>(page, limit);
        QueryWrapper<SysTraining> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("createTime");
        //queryWrapper.orderByDesc("sort");
        return baseMapper.selectPage(pageParam, queryWrapper);
    }

    /**
     * TODO 修改培训文件
     *
     * @param training 培训文件实体类
     * @return boolean
     * @author 然子哥
     * @date 2023/5/25 17:59
     */
    @Override
    public boolean updateTran(SysTraining training) {
        training.setUpdateTime(new Date());
        baseMapper.updateById(training);
        return true;
    }
    @Override
    public boolean submit(String fileName, String description, Integer projectId,Integer trainingCategoryId,MultipartFile file) {
        SysTraining training = new SysTraining();
        training.setFileName(fileName);
        training.setFileReName(file.getOriginalFilename());
        training.setDescription(description);
        training.setTrainingCategoryId(trainingCategoryId);
        training.setProjectId(projectId);
        training.setStatus(0);
        training.setSize((double) file.getSize());
        training.setType(estimateFileType(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))));
        training.setCreateTime(new Date());
        baseMapper.insert(training);
        File fileDir = new File(file.getOriginalFilename());
        try (OutputStream os = Files.newOutputStream(fileDir.toPath())) {
            IoUtil.copy(file.getInputStream(), os);
            SysTrainingServiceImpl bean = SpringUtils.getBean(this.getClass());
            bean.asyncUpload(training.getId(), fileDir);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new JGException("上传失败");
        }
        return true;
    }

    @Override
    public boolean sort(Integer id, Integer sort) {
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",id);
        updateWrapper.set("sort",sort);
        this.update(updateWrapper);
        return false;
    }

    private void getCheckFileName(String fileName,Integer projectId,Integer id) {
        List<String> fileNames =  baseMapper.selectFileName(projectId,id);
        if (fileNames.contains(fileName)){
            throw new JGException("同一项目下文件名称重复!请修改");
        }
    }

    @Override
    public boolean updateTraining(Integer id, String fileName, String description, Integer projectId, Integer trainingCategoryId, MultipartFile file) {
        SysTraining training = new SysTraining();
        //if (StringUtils.isNotBlank(fileName) && StringUtils.isNotEmpty(String.valueOf(projectId))) {
        //    getCheckFileName(fileName,projectId,id);
        //}
        if (Objects.nonNull(file))  {
            training.setId(id);
            training.setFileName(fileName);
            training.setFileReName(file.getOriginalFilename());
            training.setDescription(description);
            training.setProjectId(projectId);
            training.setTrainingCategoryId(trainingCategoryId);
            training.setSize((double) file.getSize());
            training.setType(estimateFileType(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))));
            training.setUpdateTime(new Date());
            File fileDir = new File(file.getOriginalFilename());
            try (OutputStream os = Files.newOutputStream(fileDir.toPath())) {
                IoUtil.copy(file.getInputStream(), os);
                SysTrainingServiceImpl bean = SpringUtils.getBean(this.getClass());
                bean.asyncUpload(training.getId(), fileDir);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                throw new JGException("上传失败");
            }
        } else {
            training.setId(id);
            training.setFileName(fileName);
            training.setDescription(description);
            training.setTrainingCategoryId(trainingCategoryId);
            training.setProjectId(projectId);
            training.setUpdateTime(new Date());
        }
        updateById(training);
        return true;
    }

    @Override
    public IPage<SysTrainingVo> select(SysTrainingPageParam param) {
        IPage<SysTrainingVo> sysTrainingVoIPage = baseMapper.selectTrainingPage(new Page<>(param.getCurrent(), param.getSize()), param);
        for (SysTrainingVo record : sysTrainingVoIPage.getRecords()) {
            if(null != record.getFileUrl()){
                String fileUrl = fileConfig.getPreview() + Base64Utils.encodeToString(record.getFileUrl().getBytes());
                record.setPreviewUrl(fileUrl);
            }
            record.setSize(Double.valueOf(new DecimalFormat("#.##").format(record.getSize()/1024/1024)));
        }
        return sysTrainingVoIPage;
    }

    @Override
    public SysTrainingVo selectById(Integer id) {
        return baseMapper.selectBy(id);
    }

    @Override
    public Boolean check(String fileName, Integer projectId,Integer id) {
        if (StringUtils.isNotBlank(fileName) && StringUtils.isNotBlank(String.valueOf(projectId))) {
            getCheckFileName(fileName,projectId,id);
        }
        return true;
    }

    @Override
    public List<SysTraining> getList() {
        return baseMapper.getList();
    }

    /**
     * 异步保存视频
     *
     * @param id
     * @param file
     */
    @Async("video")
    public void asyncUpload(Integer id, File file) {
        try (InputStream is = Files.newInputStream(file.toPath())) {
            String uploadFile = minioTemplate.uploadFile(file.getName(), is, null);
            file.delete();
            if (StringUtils.isNotBlank(uploadFile)) {
                baseMapper.update(null, Wrappers.<SysTraining>lambdaUpdate().eq(SysTraining::getId, id).set(SysTraining::getStatus, 1).set(SysTraining::getFileUrl,uploadFile).set(SysTraining::getUploadTime,LocalDateTime.now()));
                return;
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        baseMapper.update(null, Wrappers.<SysTraining>lambdaUpdate().eq(SysTraining::getId, id).set(SysTraining::getStatus, 2));

    }

    @Override
    public boolean updateIsDeleted(Integer id) {
        int update = baseMapper.update(null, Wrappers.<SysTraining>lambdaUpdate().eq(SysTraining::getId, id).set(SysTraining::getDeleted, 1));
        if (update > 0) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * TODO 判断文件类型
     * @author 然子哥
     * @date 2023/5/22 13:59
     * @param suffix 文件后缀
     * @return java.lang.Integer
     */
    public static Integer estimateFileType(String suffix)
    {
        if (".docx".equals(suffix) || ".doc".equals(suffix))
        {
            return 1;
        }
        if (".pptx".equals(suffix))
        {
            return 2;
        }
        if (".mp4".equals(suffix))
        {
            return 3;
        }
        if (".ppt".equals(suffix))
        {
            return 4;
        }
        if (".pdf".equals(suffix))
        {
            return 5;
        }
        return 0;
    }
}
